﻿using HslCommunication.Robot.EFORT;
using Microsoft.Win32;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZoneLineNew.Common;
using ZoneLineNew.Controls;
using ZoneLineNew.Core;
using ZoneLineNew.Core.EventArgs;
using ZoneLineNew.Models;
using ZoneLineNew.Models.Entity.StationResult;
using ZoneLineNew.Models.Package;
using ZoneLineNew.Models.StationResult.HOPStation;
using ZoneLineNew.Models.StationResult.QOPStation;
using ZoneLineNew.Services;
using ZoneLineNew.Services.DB;
using ZoneLineNew.Services.Message;
using ZoneLineNew.ViewModelBase;

namespace ZoneLineNew.ViewModels {
    public class DataHistoryViewModel : NavigationViewModel {
        public DataHistoryViewModel(
            IRegionManager regionManager,
            IDialogService dialog,
            IMessageService messageBox,
            IEventAggregator eventAggregator,
            IDbOperate<IFreeSqlMainContext> mainDbOperate
            ) : base(regionManager, dialog, messageBox, eventAggregator, mainDbOperate) {

            StationLst = new List<string> { "OP620", "OP640", "OP550", "OP560", "OP570", "OP580", "OP590" };
        }

        #region Props
        private List<object> _recordInfos;

        public List<object> RecordInfos {
            get { return _recordInfos; }
            set => SetProperty(ref _recordInfos, value);
        }

        private List<string> _stationLst;

        public List<string> StationLst {
            get { return _stationLst; }
            set => SetProperty(ref _stationLst, value);
        }

        private string _targetStation;

        public string TargetStation {
            get { return _targetStation; }
            set => SetProperty(ref _targetStation, value);
        }

        private string _code;

        public string Code {
            get { return _code; }
            set => SetProperty(ref _code, value);
        }

        private bool _timeQuery = true;

        public bool TimeQuery {
            get { return _timeQuery; }
            set => SetProperty(ref _timeQuery, value);
        }

        private bool _codeQuery;

        public bool CodeQuery {
            get { return _codeQuery; }
            set { SetProperty(ref _codeQuery, value); TargetStation = string.Empty; }
        }

        private bool _packageCodeQuery;

        /// <summary>
        /// 箱码查询
        /// </summary>
        public bool PackageCodeQuery {
            get { return _packageCodeQuery; }
            set => SetProperty(ref _packageCodeQuery, value);
        }

        private bool _packageCodeQueryRe;

        /// <summary>
        /// 通过工件码查箱码
        /// </summary>
        public bool PackageCodeQueryRe {
            get { return _packageCodeQueryRe; }
            set => SetProperty(ref _packageCodeQueryRe, value);
        }

        private bool _absCodeQuery;

        public bool AbsCodeQuery {
            get { return _absCodeQuery; }
            set => SetProperty(ref _absCodeQuery, value);
        }


        private DateTime _startDate = DateTime.Now.AddDays(-1);

        public DateTime StartDate {
            get { return _startDate; }
            set => SetProperty(ref _startDate, value);
        }

        private DateTime _endDate = DateTime.Now;

        public DateTime EndDate {
            get { return _endDate; }
            set { _endDate = value; }
        }

        private DateTime _startTime = DateTime.Today.AddHours(0).AddMinutes(0).AddSeconds(0);//DateTime.Now;

        /// <summary>
        /// 开始时间
        /// </summary>
        public DateTime StartTime {
            get { return _startTime; }
            set => SetProperty(ref _startTime, value);
        }

        private DateTime _endTime = DateTime.Today.AddHours(23).AddMinutes(59).AddSeconds(59);// DateTime.Now;

        /// <summary>
        /// 结束时间
        /// </summary>
        public DateTime EndTime {
            get { return _endTime; }
            set => SetProperty(ref _endTime, value);
        }

        private bool _isLoading;

        public bool IsLoading {
            get { return _isLoading; }
            set => SetProperty(ref _isLoading, value);
        }

        #endregion

        public DelegateCommand QueryDataCmd => new DelegateCommand(async () => {

            var (isOk, startTime, endTime) = Tuple.Create(false, DateTime.Now, DateTime.Now);
            if (TimeQuery) {
                if (string.IsNullOrEmpty(TargetStation)) {
                    _message.Warning("请选择工位！");
                    return;
                }

                (isOk, startTime, endTime) = CheckCondition();
                if (!isOk) {
                    _message.Warning("请检查时间格式！");
                    return;
                }
            }
            if (CodeQuery && string.IsNullOrEmpty(Code)) {
                _message.Warning("请先输入条码！");
                return;
            }

            await Task.Run(() => {
                try {
                    RecordInfos = null;
                    if (TimeQuery) {
                        IsLoading = true;
                        List<object> temp = null;
                        switch (TargetStation) {
                            case "OP620":
                                temp = QueryData<HOP010StationResult>(startTime, endTime);
                                break;

                            case "OP640":
                                temp = QueryData<HOP040StationResult>(startTime, endTime);
                                break;

                            case "OP550":
                                temp = QueryData<QOP006StationResult>(startTime, endTime);
                                break;

                            case "OP570":
                                temp = QueryData<QOP010StationResult>(startTime, endTime);
                                break;

                            case "OP560":
                                temp = QueryData<QOP020StationResult>(startTime, endTime);
                                break;

                            case "OP580":
                                temp = QueryData<QOP050LStationResult>(startTime, endTime);
                                break;

                            case "OP590":
                                temp = QueryData<QOP050RStationResult>(startTime, endTime);
                                break;

                            case "OP610":
                                temp = QueryData<QOP060StationResult>(startTime, endTime);
                                break;

                            default:
                                break;
                        }

                        RecordInfos = temp;
                    }
                    if (CodeQuery) {
                        if (string.IsNullOrEmpty(Code)) {
                            return;
                        }
                        IsLoading = true;

                        if (Cache.IsQopStaion == true) {
                            var op006Result = _mainDbOperate.GetModel<QOP006StationResult>(p => p.Code == Code);
                            var op010Result = _mainDbOperate.GetModel<QOP010StationResult>(p => p.Code == Code);
                            var op020Result = _mainDbOperate.GetModel<QOP020StationResult>(p => p.Code == Code);
                            var op050LResult = _mainDbOperate.GetModel<QOP050LStationResult>(p => p.Code == Code);
                            var op050RResult = _mainDbOperate.GetModel<QOP050RStationResult>(p => p.Code == Code);
                            if (!(op006Result == null && op010Result == null && op020Result == null && op050LResult == null && op050RResult == null)) {
                                var model = new HOpResultModel { Code = Code, CreateTime = op050LResult != null ? op050LResult.CreateTime : op050RResult != null ? op050RResult.CreateTime : DateTime.Now, Op06Result = op006Result?.Result, Op010Result = op010Result?.Result, Op020Result = op020Result?.Result, Op050LResult = op050LResult?.Result, Op050RResult = op050RResult?.Result };
                                RecordInfos = new List<object> { model };
                            }
                        } else if (Cache.IsHopStaion == true) {
                            var op010Result = _mainDbOperate.GetModel<HOP010StationResult>(p => p.Code == Code);
                            var op040Result = _mainDbOperate.GetModel<HOP040StationResult>(p => p.Code == Code);

                            if (!(op010Result == null && op040Result == null)) {
                                var model = new QOpResultModel { Code = Code, CreateTime = op010Result != null ? op010Result.CreateTime : op040Result != null ? op040Result.CreateTime : DateTime.Now, Op010Result = op010Result?.Result, Op040Result = op040Result?.Result, };
                                RecordInfos = new List<object> { model };
                            }
                        }

                        IsLoading = false;
                    } else if (PackageCodeQuery) {
                        //查询打印码
                        var absPrintCodeRlts = _mainDbOperate.GetModelList<PackageResult>(p => p.BoxCode == Code);
                        var models = new List<object>();
                        foreach (var item in absPrintCodeRlts) {
                            models.Add(item);
                        }
                        RecordInfos = models;
                    } else if (AbsCodeQuery) {
                        if (string.IsNullOrEmpty(Code)) {
                            return;
                        }
                        IsLoading = true;

                        if (Cache.IsQopStaion) {
                            var op006Result = _mainDbOperate.GetModel<QOP006StationResult>(p => p.AbsScanCode == Code);
                            var op010Result = _mainDbOperate.GetModel<QOP010StationResult>(p => p.AbsScanCode == Code);
                            var op020Result = _mainDbOperate.GetModel<QOP020StationResult>(p => p.AbsScanCode == Code);
                            var op050LResult = _mainDbOperate.GetModel<QOP050LStationResult>(p => p.AbsScanCode == Code);
                            var op050RResult = _mainDbOperate.GetModel<QOP050RStationResult>(p => p.AbsScanCode == Code);

                            if (op006Result != null || op010Result != null || op020Result != null || op050LResult != null || op050RResult != null) {
                                var model = new HOpResultModel { Code = Code, CreateTime = op050LResult != null ? op050LResult.CreateTime : op050RResult != null ? op050RResult.CreateTime : DateTime.Now, Op06Result = op006Result?.Result, Op010Result = op010Result?.Result, Op020Result = op020Result?.Result, Op050LResult = op050LResult?.Result, Op050RResult = op050RResult?.Result };
                                RecordInfos = new List<object> { model };
                            }
                        } else if (Cache.IsHopStaion) {
                            var op010Result = _mainDbOperate.GetModel<HOP010StationResult>(p => p.AbsScanCode == Code);
                            var op040Result = _mainDbOperate.GetModel<HOP040StationResult>(p => p.AbsScanCode == Code);

                            if (op010Result != null || op040Result != null) {
                                var model = new QOpResultModel { Code = Code, CreateTime = op010Result != null ? op010Result.CreateTime : op040Result != null ? op040Result.CreateTime : DateTime.Now, Op040Result = op040Result?.Result, Op010Result = op010Result?.Result, };
                                RecordInfos = new List<object> { model };
                            }
                        }

                        IsLoading = false;
                    } else if (PackageCodeQueryRe) {
                        var packageTemp = _mainDbOperate.GetModel<PackageResult>(p => p.Code == Code);
                        if (packageTemp != null) {
                            //查询打印码
                            var absPrintCodeRlts = _mainDbOperate.GetModelList<PackageResult>(p => p.BoxCode == packageTemp.BoxCode);
                            var models = new List<object>();
                            foreach (var item in absPrintCodeRlts) {
                                models.Add(item);
                            }
                            RecordInfos = models;
                        }
                    }
                    IsLoading = false;
                } catch (Exception ex) {
                    _message.Error($"查询数据失败{ex.Message}");
                }
            });

        });


        public DelegateCommand ExportCmd => new DelegateCommand(() => {
            ExportData();
        });

        public DelegateCommand OpenInfoCmd => new DelegateCommand(() => {

            //_message.GrowlInfo("该功能正在开发中....");
        });

        


        protected override void OnViewLoaded() {
            _eventAggregator.GetEvent<PubSubEventArgs>().Unsubscribe(GetScanBarCode);
            _eventAggregator.GetEvent<PubSubEventArgs>().Subscribe(GetScanBarCode);
            //base.OnViewLoaded();
        }

        public override void OnNavigatedFrom(NavigationContext navigationContext) {
            _eventAggregator.GetEvent<PubSubEventArgs>().Unsubscribe(GetScanBarCode);
            //base.OnNavigatedFrom(navigationContext);
        }

        private void GetScanBarCode(MessageData messageData) {
            if (messageData.Code == NonClientAreaControl._scanCode && messageData.Parameters.ContainsKey("Content")) {
                this.Code = messageData.Parameters.GetValue<string>("Content");
            }
        }

        private List<object> QueryData<T>(DateTime startTime, DateTime endTime) where T : StationResultBase, new() {
            var temp = new List<object> { };
            var sql = $@"select a.*,b.BoxCode as BoxCodeView
                         from {typeof(T).Name} a
                         left join packageresult b on a.AbsScanCode = b.AbsCode
                         where (AbsScanCode !='' and AbsScanCode is not null) and CreateTime between '{startTime.ToString("yyyy-MM-dd HH:mm:ss")}' and '{endTime.ToString("yyyy-MM-dd HH:mm:ss")}';";
            var result = _mainDbOperate.ExceSqlToList<T>(sql);

            for (var i = 0; i < result.Count; i++) {
                temp.Add(result[i]);
            }
            return temp;
        }

        private Tuple<bool, DateTime, DateTime> CheckCondition() {
            var startTime = new DateTime(StartDate.Year, StartDate.Month, StartDate.Day, StartTime.Hour, StartTime.Minute, StartTime.Second);
            var endTime = new DateTime(EndDate.Year, EndDate.Month, EndDate.Day, EndTime.Hour, EndTime.Minute, EndTime.Second);
            var success = true;
            if (endTime < startTime) {
                _message.Warning("结束时间不能小于开始时间，请检查!");
                success = false;
            }
            return Tuple.Create(success, startTime, endTime);
        }


        /// <summary>
        /// 导出数据
        /// </summary>
        private async void ExportData() {
            try {
                SaveFileDialog dia = new SaveFileDialog();
                dia.Filter = "*.xlsx|*.*";
                dia.DefaultExt = "xlsx";
                dia.AddExtension = true;
                var rlt = dia.ShowDialog();

                if (rlt.HasValue && rlt.Value) {
                    IsLoading = true;
                    var path = dia.FileName;
                    //if (TimeQuery && string.IsNullOrEmpty(TargetStation))
                    if (TimeQuery) {
                        var tempStationList = string.IsNullOrEmpty(TargetStation) ? StationLst.ToList() : StationLst.Where(o => o == TargetStation);
                        List<object> temp = null;
                        var (isOk, startTime, endTime) = Tuple.Create(false, DateTime.Now, DateTime.Now);

                        (isOk, startTime, endTime) = CheckCondition();
                        //foreach (var item in StationLst)
                        foreach (var item in tempStationList) {
                            switch (item) {
                                case "OP620":
                                    temp = QueryData<HOP010StationResult>(startTime, endTime);
                                    break;

                                case "OP640":
                                    temp = QueryData<HOP040StationResult>(startTime, endTime);
                                    break;

                                case "OP550":
                                    temp = QueryData<QOP006StationResult>(startTime, endTime);
                                    break;

                                case "OP570":
                                    temp = QueryData<QOP010StationResult>(startTime, endTime);
                                    break;

                                case "OP560":
                                    temp = QueryData<QOP020StationResult>(startTime, endTime);
                                    break;

                                case "OP580":
                                    temp = QueryData<QOP050LStationResult>(startTime, endTime);
                                    break;

                                case "OP590":
                                    temp = QueryData<QOP050RStationResult>(startTime, endTime);
                                    break;

                                case "OP610":
                                    temp = QueryData<QOP060StationResult>(startTime, endTime);
                                    break;
                            }
                            if (temp != null && temp.Count > 0) {
                                await Task.Run(() => {
                                    NPOIService.ExportToExcel(path, temp, sheetName: item);
                                });
                            }
                        }
                    }

                    if (CodeQuery && !string.IsNullOrEmpty(Code)) {
                        List<object> temp = null;
                        foreach (var item in StationLst) {
                            switch (item) {
                                case "OP620":
                                    temp = QueryDataByScanCode<HOP010StationResult>(Code);
                                    break;

                                case "OP640":
                                    temp = QueryDataByScanCode<HOP040StationResult>(Code);
                                    break;

                                case "OP550":
                                    temp = QueryDataByScanCode<QOP006StationResult>(Code);
                                    break;

                                case "OP570":
                                    temp = QueryDataByScanCode<QOP010StationResult>(Code);
                                    break;

                                case "OP560":
                                    temp = QueryDataByScanCode<QOP020StationResult>(Code);
                                    break;

                                case "OP580":
                                    temp = QueryDataByScanCode<QOP050LStationResult>(Code);
                                    break;

                                case "OP590":
                                    temp = QueryDataByScanCode<QOP050RStationResult>(Code);
                                    break;

                                case "OP610":
                                    temp = QueryDataByScanCode<QOP060StationResult>(Code);
                                    break;
                            }
                            if (temp != null && temp.Count > 0) {
                                await Task.Run(() => {
                                    NPOIService.ExportToExcel(path, temp, sheetName: item);
                                });
                            }
                        }

                        if (RecordInfos == null || RecordInfos.Count < 1) {
                            _message.Error("不存在要导出的数据，请查到数据后再导出！");
                            return;
                        }
                        await Task.Run(() => {
                            NPOIService.ExportToExcel(path, RecordInfos);
                        });
                    }

                    IsLoading = false;
                }
            } catch (Exception ex) {
                IsLoading = false;
                LogManager.Error(ex);
            }
        }

        private List<object> QueryDataByScanCode<T>(string code) where T : StationResultBase, new() {
            var temp = new List<object> { };
            var hOP010Result = _mainDbOperate.GetModelList<T>(p => p.AbsScanCode.Equals(code));

            for (var i = 0; i < hOP010Result.Count; i++) {
                temp.Add(hOP010Result[i]);
            }
            return temp;
        }

    }
}
